﻿#region Creditos

/* Autor: Edilberto Sánchez Forero	*/
/* Email: esanchezfo@gmail.com		*/
/* Licencia: LGPL, Software Libre	*/
/* País: Colombia, Bogotá			*/

#endregion

#region Librerias

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Linq.Expressions;
using System.Xml;

#endregion


namespace ESF.General.Entity
{
	[DataContract]
	[Serializable]
	public class BrowseResults<O>
	{
		[DataMember]
		public PaggingInfo PaggingInfo { set; get; }
		
		[DataMember]
		public List<O> Results { set; get; }

		[DataMember]
		public long calProcessingDurationms { set; get; }


		#region Funcion

		public static BrowseResults<E> GetInstanceWithOrder<E, TOrderbyType> (Table<E> pTable, Expression<Func<E,bool>> pWhere, Expression<Func<E,TOrderbyType>> pOrderBy, PaggingInfo pPagInfo)
		where E : class
		{
			pPagInfo.RowCount = pTable.Count (pWhere);

			return new BrowseResults<E> () { 
				Results = pTable.
					Where (pWhere).
					OrderBy (pOrderBy).
					Skip (pPagInfo.PageSize * pPagInfo.PageIndex).
					Take (pPagInfo.PageSize).
					ToList (), 
				PaggingInfo = pPagInfo };
		}


		public static BrowseResults<E> GetInstanceWithOrderDesc<E, TOrderbyType> (Table<E> pTable, Expression<Func<E,bool>> pWhere, Expression<Func<E,TOrderbyType>> pOrderBy, PaggingInfo pPagInfo)
		where E : class
		{
			pPagInfo.RowCount = pTable.Count (pWhere);

			return new BrowseResults<E> () { 
				Results = pTable.
					Where (pWhere).
					OrderByDescending (pOrderBy).
					Skip (pPagInfo.PageSize * pPagInfo.PageIndex).
					Take (pPagInfo.PageSize).
					ToList (), 
				PaggingInfo = pPagInfo };
		}


		public static BrowseResults<E> GetInstance<E> (Table<E> pTable, Expression<Func<E,bool>> pWhere, PaggingInfo pPagInfo)
		where E : class
		{
			pPagInfo.RowCount = pTable.Count (pWhere);

			return new BrowseResults<E> () { 
				Results = pTable.Where (pWhere).
					Skip (pPagInfo.PageSize * pPagInfo.PageIndex).
					Take (pPagInfo.PageSize).
					ToList (), 
				PaggingInfo = pPagInfo };
		}

		#endregion


		public void ConvertToXML(XmlWriter pXmlWriter, Action<XmlWriter, O, bool> pConverterToXML)
		{
			ConvertToXML<O> (pXmlWriter, this, pConverterToXML);
		}


		public static void ConvertToXML<T> (XmlWriter pXmlWriter, BrowseResults<T> pResults, Action<XmlWriter, T, bool> pConverterToXML)
		{
			pXmlWriter.WriteStartElement ("BrowseResults");

				pXmlWriter.WriteAttributeString ("ProcessingDurationms", pResults.calProcessingDurationms.ToString ());

				pResults.PaggingInfo.ConvertToXML(pXmlWriter);
				
				foreach (T item in pResults.Results)
				{
					pConverterToXML (pXmlWriter, item, false);
				}

			pXmlWriter.WriteEndElement ();
		}
	}
}
